package com.ddwl.goods.service;

import com.ddwl.common.constant.ItemTrialEnum;
import com.ddwl.common.exception.CommonException;
import com.ddwl.common.util.BeanConverUtils;
import com.ddwl.common.util.MySqlUtil;
import com.ddwl.common.util.UUIDGenerator;
import com.ddwl.goods.dao.CategoryDao;
import com.ddwl.goods.dao.ItemTrialDao;
import com.ddwl.goods.mapper.ItemMapper;
import com.ddwl.goods.model.Category;
import com.ddwl.goods.model.Item;
import com.ddwl.goods.model.ItemTrial;
import com.ddwl.schema.bo.base.PageBo;
import com.ddwl.schema.bo.goods.ItemSearchBo;
import com.ddwl.schema.bo.goods.ItemTrialBo;
import com.ddwl.schema.bo.goods.ItemTrialDetBo;
import com.ddwl.schema.vo.base.PageVo;
import com.ddwl.schema.vo.goods.ItemConListVo;
import com.ddwl.schema.vo.goods.ItemTrialVo;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class ItemTrialService {
    @Autowired
    public ItemTrialDao itemTrialDao;
    @Autowired
    public ItemMapper itemMapper;
    @Resource
    private CategoryDao categoryDao;

    /**
     * 根据审核阶段，审核状态查询审核列表
     *
     * @param pageBo
     * @return
     */
    public PageVo<ItemTrialVo> list(PageBo<ItemTrialBo> pageBo) {
        PageHelper.startPage(pageBo.getPage(), pageBo.getPageSize(), MySqlUtil.orderBy(pageBo.getSort(), pageBo.isAsc()));
        ItemTrialBo itemTrialBo = pageBo.getParam();
        List<ItemTrial> itemTrials = itemTrialDao.select(BeanConverUtils.convertBean(itemTrialBo, ItemTrial.class));
        PageInfo<ItemTrial> pageInfo = new PageInfo(itemTrials);
        List<ItemTrialVo> itemTrialVos = BeanConverUtils.convertBeanList(pageInfo.getList(), ItemTrialVo.class);
        return new PageVo<>(pageInfo.getTotal(), pageBo.getPage(), pageBo.getPageSize(), itemTrialVos);
    }

    /**
     * 下架申请审核列表
     *
     * @param pageBo
     * @return
     */
    public PageVo<ItemConListVo> undercarriageList(PageBo<ItemSearchBo> pageBo) {
        PageHelper.startPage(pageBo.getPage(), pageBo.getPageSize(), MySqlUtil.orderBy(pageBo.getSort(), pageBo.isAsc()));
        ItemSearchBo itemSearchBo = pageBo.getParam();
        Page<Item> pageable = (Page<Item>) itemMapper.findConAllNew(itemSearchBo);
        List<Item> entities = pageable.getResult();
        if (entities.isEmpty()) {
            return new PageVo<>(pageable.getTotal(), pageBo.getPage(), pageBo.getPageSize(), new ArrayList<>());
        }
        List<ItemTrial> itemTrials = itemTrialDao.selectByItemIds(entities.stream().map(Item::getId).collect(Collectors.toList()));
        Map<String, ItemTrial> itemTrialMap = itemTrials.stream().collect(Collectors.toMap(ItemTrial::getItemId, Function.identity(), (k1, k2) -> k1));
        //获取分类名称
        List<Category> categories = categoryDao.selectAll();
        Map<String, String> categoryMap = categories.stream().collect(Collectors.toMap(Category::getId, Category::getName));
        List<ItemConListVo> itemVos = entities.stream().map(item -> {
            ItemConListVo vo = BeanConverUtils.convertBean(item, ItemConListVo.class);
            if (item.getItemSgin() != null) {
                String[] sgins = item.getItemSgin().split(",");
                List<String> sginList = new ArrayList<>();
                for (String sgin : sgins) {
                    if (!sgin.equals("")) {
                        sginList.add(sgin);
                    }
                }
                vo.setItemSgins(sginList);
            }
            vo.setCategoryName(categoryMap.get(item.getCategoryId()));
            ItemTrial itemTrial = itemTrialMap.getOrDefault(item.getId(), new ItemTrial());
            vo.setAuditingStatus(itemTrial.getAuditingStatus());
            vo.setRefuseReason(itemTrial.getRefuseReason());
            vo.setIsAuditingPass(itemTrial.getIsAuditingPass());
            vo.setUndercarriageReason(itemTrial.getUndercarriageReason());
            vo.setUndercarriageRefuseReason(itemTrial.getUndercarriageRefuseReason());
            vo.setIsStacking(itemTrial.getIsStacking());
            return vo;
        }).collect(Collectors.toList());
        return new PageVo<>(pageable.getTotal(), pageBo.getPage(), pageBo.getPageSize(), itemVos);
    }

    /**
     * 审批---通过
     *
     * @param itemTrialDetBo
     */
    @Transactional(rollbackFor = Throwable.class)
    public void approvePass(ItemTrialDetBo itemTrialDetBo) {
        List<String> itemIds = itemTrialDetBo.getItemIds();
        List<ItemTrial> itemTrials = new ArrayList<>();
        //审核通过更改isAuditingPass为通过
        for (String id : itemIds) {
            ItemTrial itemTrial = new ItemTrial();
            itemTrial.setIsAuditingPass(ItemTrialEnum.IsAudithingPass.PASS.getCode());
            itemTrial.setItemId(id);
            itemTrial.setAuditingStage(itemTrialDetBo.getAuditingStage());
            itemTrials.add(itemTrial);
            //清空上一阶段审核驳回原因
            itemTrialDao.updateRefuseReasonNull(id, itemTrialDetBo.getAuditingStage() - 1);
        }
        itemTrialDao.updateListByItemIdAndStage(itemTrials);
        //只有复审阶段通过的才更新创建和初审的审核状态为提交的审核通过
        if (itemTrialDetBo.getAuditingStage().equals(ItemTrialEnum.AuditingStage.RECHECK.getCode())) {
            itemTrialDao.updatePass(itemIds);
            itemTrialDao.updateStackingStatus(itemIds, ItemTrialEnum.IsStacking.UNGROUNDING.getCode());
        }

    }

    /**
     * 审批---拒绝
     */
    @Transactional(rollbackFor = Throwable.class)
    public void approveRefuse(ItemTrialDetBo itemTrialDetBo) {
        List<String> itemIds = itemTrialDetBo.getItemIds();
        List<ItemTrial> itemTrialsA = new ArrayList<>();
        List<ItemTrial> itemTrialsB = new ArrayList<>();
        for (String itemId : itemIds) {
            //审核拒绝更改isAuditingPass为拒绝
            ItemTrial itemTriala = new ItemTrial();
            ItemTrial itemTrialb = new ItemTrial();
            itemTriala.setIsAuditingPass(ItemTrialEnum.IsAudithingPass.REFUSE.getCode());
            itemTriala.setItemId(itemId);
            itemTriala.setAuditingStage(itemTrialDetBo.getAuditingStage());
            itemTrialsA.add(itemTriala);
            //更改上一层的审核状态为审批拒绝,并更新拒绝原因
            itemTrialb.setAuditingStage(ItemTrialEnum.AuditingStage.CREATE.getCode());
            itemTrialb.setItemId(itemId);
            itemTrialb.setRefuseReason(itemTrialDetBo.getRefuseReason());
            itemTrialb.setAuditingStatus(ItemTrialEnum.AuditingStatus.AUDITING_REFUSE.getCode());
            itemTrialsB.add(itemTrialb);
        }
        itemTrialDao.updateListByItemIdAndStage(itemTrialsA);
        itemTrialDao.updateListByItemIdAndStage(itemTrialsB);
        itemTrialDao.deleteAuditing(itemIds, itemTrialDetBo.getAuditingStage());
        if (itemTrialDetBo.getAuditingStage().equals(ItemTrialEnum.AuditingStage.RECHECK.getCode())) {
            itemTrialDao.deleteAuditing(itemIds, ItemTrialEnum.AuditingStage.FIRST_TRIAL.getCode());
        }
    }

    /**
     * 提交审批
     *
     * @param itemTrialDetBo
     * @return
     */
    @Transactional(rollbackFor = Throwable.class)
    public Integer submitApprove(ItemTrialDetBo itemTrialDetBo) {
        List<String> itemIds = itemTrialDetBo.getItemIds();
        List<ItemTrial> itemTrialsA = new ArrayList<>();
        List<ItemTrial> itemTrialsB = new ArrayList<>();
        for (String itemId : itemIds) {
            ItemTrial itemTriala = new ItemTrial();
            ItemTrial itemTrialb = new ItemTrial();
            ItemTrial itemTrialfind = new ItemTrial();
            itemTrialfind.setItemId(itemId);
            itemTrialfind.setAuditingStage(itemTrialDetBo.getAuditingStage());
            ItemTrial itemTrial = itemTrialDao.selectOne(itemTrialfind);
            //只有初审的需要检测一下是否是审批过的记录才可以提交
            if (itemTrialDetBo.getAuditingStage().equals(ItemTrialEnum.AuditingStage.FIRST_TRIAL.getCode()) && itemTrial.getIsAuditingPass() == null) {
                throw new CommonException("商品id" + itemId + "的记录没有审批过，无法提交");
            }
            //更改该层提交的审核状态为审核中
            itemTriala.setAuditingStatus(ItemTrialEnum.AuditingStatus.AUDITING_PROCESS.getCode());
            itemTriala.setItemId(itemId);
            itemTriala.setAuditingStage(itemTrialDetBo.getAuditingStage());
            itemTrialsA.add(itemTriala);
            //插入提交下一层审核状态为待审核的商品审核信息
            itemTrialb.setAuditingStage(itemTrialDetBo.getAuditingStage() + 1);
            itemTrialb.setItemId(itemId);
            itemTrialb.setAuditingStatus(ItemTrialEnum.AuditingStatus.AUDITING_NOT.getCode());
            itemTrialsB.add(itemTrialb);
        }
        itemTrialDao.updateListByItemIdAndStage(itemTrialsA);
        return itemTrialDao.insertList(itemTrialsB);
    }

    /**
     * 撤销审批
     */
    @Transactional(rollbackFor = Throwable.class)
    public void cancelApprove(ItemTrialDetBo itemTrialDetBo) {
        //只有审核状态为审核中的商品才可以撤销审核
        ItemTrial itemTrial = new ItemTrial();
        itemTrial.setItemId(itemTrialDetBo.getItemIds().get(0));
        itemTrial.setAuditingStage(itemTrialDetBo.getAuditingStage());
        ItemTrial itemTrialfind = itemTrialDao.selectOne(itemTrial);
        if (!itemTrialfind.getAuditingStatus().equals(ItemTrialEnum.AuditingStatus.AUDITING_PROCESS.getCode())) {
            throw new CommonException("只有审核中的商品才可以撤销审核！");
        }
        //1.更新该阶段的审核状态为待审核2.删除下一级或多级的商品审核记录
        itemTrial.setAuditingStatus(ItemTrialEnum.AuditingStatus.AUDITING_NOT.getCode());
        List<ItemTrial> itemTrials = new ArrayList<>();
        itemTrials.add(itemTrial);
        itemTrialDao.updateListByItemIdAndStage(itemTrials);
        //创建阶段还要删除初审的信息
        if (itemTrialDetBo.getAuditingStage().equals(ItemTrialEnum.AuditingStage.CREATE.getCode())) {
            itemTrialDao.deleteAuditing(itemTrialDetBo.getItemIds(), ItemTrialEnum.AuditingStage.FIRST_TRIAL.getCode());
        }
        itemTrialDao.deleteAuditing(itemTrialDetBo.getItemIds(), ItemTrialEnum.AuditingStage.RECHECK.getCode());
    }

    /**
     * 申请下架
     */
    @Transactional(rollbackFor = Throwable.class)
    public void undercarriage(ItemTrialBo itemTrialBo) {
        List<ItemTrial> itemTrials = new ArrayList<>();
        itemTrials.add(BeanConverUtils.convertBean(itemTrialBo, ItemTrial.class));
        itemTrialDao.updateListByItemIdAndStage(itemTrials);
        ItemTrial itemTrial = new ItemTrial();
        itemTrials.clear();
        itemTrial.setItemId(itemTrialBo.getItemId());
        itemTrial.setAuditingStage(ItemTrialEnum.AuditingStage.RECHECK.getCode());
        itemTrial.setUndercarriageReason(itemTrialBo.getUndercarriageReason());
        itemTrials.add(itemTrial);
        itemTrialDao.updateListByItemIdAndStage(itemTrials);
        itemTrialDao.updateUndercarriageRefuseReasonNull(itemTrialBo.getItemId(), ItemTrialEnum.AuditingStage.CREATE.getCode());
    }

    /**
     * 下架申请驳回
     *
     * @param itemTrialBo
     */
    @Transactional(rollbackFor = Throwable.class)
    public void undercarriageRefuse(ItemTrialBo itemTrialBo) {
        List<ItemTrial> itemTrialList = new ArrayList<>();
        itemTrialList.add(BeanConverUtils.convertBean(itemTrialBo, ItemTrial.class));
        itemTrialDao.updateListByItemIdAndStage(itemTrialList);
        ItemTrial itemTrial = new ItemTrial();
        itemTrialList.clear();
        itemTrial.setItemId(itemTrialBo.getItemId());
        itemTrial.setAuditingStage(ItemTrialEnum.AuditingStage.CREATE.getCode());
        itemTrial.setUndercarriageRefuseReason(itemTrialBo.getUndercarriageRefuseReason());
        itemTrialList.add(itemTrial);
        itemTrialDao.updateListByItemIdAndStage(itemTrialList);
        itemTrialDao.updateUndercarriageReason(itemTrialBo.getItemId(), ItemTrialEnum.AuditingStage.RECHECK.getCode());
    }

    public void changeId() {
        List<ItemTrial> list = itemTrialDao.getAll();
        if (!CollectionUtils.isEmpty(list)) {
            Map<String, String> map = new HashMap<>();
            for (ItemTrial it : list) {
                String id = it.getId();
                if (id.length() == 11) {
                    long longId = UUIDGenerator.reverseShortUUID(id);
                    map.put(id, String.valueOf(longId));
                }
            }
            if (!CollectionUtils.isEmpty(map)) {
                itemTrialDao.changeId(map);
            }
        }
    }
}
